/**
 * Copyright c FOUNDER CORPORATION 2006 All Rights Reserved.
 * DbUtil.java
 */
package com.iori.common.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.Torque;
import org.apache.torque.TorqueException;
import org.apache.torque.util.Transaction;

/**
 *
 * [クラス名]<br>
 *  DbUtil<br><br>
 * [機能概要]<br>
 *  データベースアクセス用のユーティリティクラス<br>
 * [変更履歴]<br>
 *  2006/07/11 ver1.00 新規作成 zhanjc<br>
 *  <br>
 *
 * @author zhanjc
 * @version 1.00
 */
public class DbUtil {
	/**
	 * ログ出力用のインスタンス生成。
	 */
	protected static Log logger = LogFactory.getLog(DbUtil.class);

	/**
	 * パラメータの型をチェックし、暗黙的にStringに変換する。
	 *
	 * @param value パラメーター
	 * @return 表示用にString型に変更されたvalue
	 */
	public static String objectToString(Object value) {

		if (value == null) {
			return null;
		} else if (value instanceof java.math.BigDecimal) {
			return ((java.math.BigDecimal) value).toString();
		} else if (value instanceof java.lang.Boolean) {
			return ((java.lang.Boolean) value).toString();
		} else if (value instanceof java.lang.Byte) {
			return ((java.lang.Byte) value).toString();
		} else if (value instanceof byte[]) {
			StringBuffer sb = new StringBuffer();
			byte[] b = (byte[]) value;
			for (int i = 0; i < b.length; i++)
				sb.append(Integer.toHexString(b[i]));
			return sb.toString();
		} else if (value instanceof java.sql.Date) {
			Date d = new Date(((java.sql.Date) value).getTime());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
			return sdf.format(d);
		} else if (value instanceof java.lang.Double) {
			return ((java.lang.Double) value).toString();
		} else if (value instanceof java.lang.Float) {
			return ((java.lang.Float) value).toString();
		} else if (value instanceof java.lang.Integer) {
			return ((java.lang.Integer) value).toString();
		} else if (value instanceof java.lang.Long) {
			return ((java.lang.Long) value).toString();
		} else if (value instanceof java.lang.Short) {
			return ((java.lang.Short) value).toString();
		} else if (value instanceof java.lang.String) {
			return (java.lang.String) value;
		} else if (value instanceof java.sql.Time) {
			Date d = new Date(((java.sql.Time) value).getTime());
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
			return sdf.format(d);
		} else if (value instanceof java.sql.Timestamp) {
			Date d = new Date(((java.sql.Timestamp) value).getTime());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			return sdf.format(d);
		} else if (value instanceof Throwable) {
			return ((Throwable) value).toString();
		} else {
			return value.toString();
		}
	}

	/**
	 * SQL文にて｢'｣文字を「’’」に切り替えする
	 *
	 * @param val String 変換Sql文字列
	 * @return String　変換した文字列
	 *
	 */
	public static String repSql(String val) {
		if (val == null || "".equals(val)) {
			return "";
		}
		String ret = "";
		int end = val.indexOf('\'');
		int start = 0;
		while (end >= 0) {
			ret += val.substring(start, end) + "''";
			start = end + 1;
			end = val.indexOf('\'', start);
		}
		ret += val.substring(start);
		return ret;
	}

	/**
	 * SQL文にて｢?｣をパラメータ値に切り替えする
	 *
	 * @param sql String 変換Sql文字列
	 * @param param String 変換Sql文字列
	 * @return String　変換した文字列
	 *
	 */
	public static String repSqlParam(String sql, Object param) {
		String ret = "";
		int i = sql.indexOf('?');
		if (i > 0) {
			ret = sql.substring(0, i);
			if (param != null) {
				if (param instanceof String) {
					ret += "'" + repSql((String) param) + "'";
				} else {
					ret += param.toString();
				}
			} else {
				ret += "null";
			}
			ret += sql.substring(i+1);
		}
		return ret;
	}

	/**
	 * コミットする
	 *
	 * @param con DBコネクション
	 * @throws SQLException
	 */
	public static void commit(Connection con) throws SQLException, TorqueException {

		Transaction.commit(con);
	}

	/**
	 * ロールバックする
	 *
	 * @param con DBコネクション
	 * @throws SQLException
	 */
	public static void rollback(Connection con) throws SQLException, TorqueException {

		Transaction.rollback(con);
	}

	/**
	 * データソースからコネクションを取得して、引数によってトランザクションを開始する
	 *
	 * @param dbName データベース名
	 * @param useTransaction トランザクション開始フラグ
	 * @return Connection DBコネクション
	 * @throws SQLException
	 */
	public static Connection beginOptional(String dbName, boolean useTransaction) throws SQLException, TorqueException {

		return Transaction.beginOptional(dbName, useTransaction);
	}

	/**
	 * データソースからコネクションを取得して、トランザクションを開始する
	 *
	 * @param dbName データベース名
	 * @return Connection DBコネクション
	 * @throws SQLException
	 */
	public static Connection begin(String dbName) throws SQLException, TorqueException {

		return Transaction.begin(dbName);
	}

	/**
	 * 安全でロールベックする
	 *
	 * @param con DBコネクション
	 */
	public static void safeRollback(Connection con) {

		Transaction.safeRollback(con);
	}

	/**
	 * コネクションを閉じる
	 *
	 * @param con DBコネクション
	 */
	public static void closeConnection(Connection con) {

		Torque.closeConnection(con);
	}

	/**
	 * 文字の並べた交替した結果を返する
	 *
	 * @param sVal フォーマット値
	 * @param oldVal 交替する文字は並べる
	 * @param repVal 交替した文字が並べることに用いる
	 * @return String 文字の並べた交替した結果を返する
	 */
	public static String replace(String sVal, String oldVal,  String repVal) {
		if (sVal == null || oldVal == null || repVal == null) {
			return sVal;
		}
		StringBuffer result = new StringBuffer(sVal);
		String str = new String(sVal);

		int preLength = 0;
		int newEndPost = 0;
		while (str.toString().indexOf(oldVal) >= 0) {
			int startPost = preLength + str.toString().indexOf(oldVal);
			int endPost = startPost +  oldVal.length();

			result.delete(startPost, endPost);
			result.insert(startPost, repVal);

			newEndPost = startPost + repVal.length();
			str = result.substring(newEndPost,result.length());
			preLength = newEndPost;
		}
		return result.toString();
	}
}
